Solving 10385 - Duathlon (Ternary search)
[and.git] / 209 - Triangular vertices / Problem209.pas
bloba3d383177b622b9d3be22563ae145192ee1ca60e
1 program problem209 (input, output);
3 type
4 TPunto = Record
5 Num, Fila,
6 PosIzq, //La posición del punto contando desde el primer elemento de la izquierda de la fila
7 PosDcha //Lo mismo pero empezando por la derecha
8 : Integer;
9 end;
11 var
12 i, j, Distancia1 : integer;
13 Entrada : String;
14 Puntos : Array[0..5] of TPunto; //los puntos en el orden en que entran
15 PuntosOrdenados : Array[0..5] of TPunto; //los puntos ordenados de mayor a menor
16 Cuenta : Integer; //Cuenta el numero de puntos que le entraron - 1 (Porque el arreglo empieza en 0)
17 TempPt : TPunto; //Pt temporal usado para organizarlos de mayor a menor
19 PtsCorrectos : Set of Byte;
21 Function StrToInt(Const S: String): Integer;
22 Var
23 E: Integer;
24 Begin
25 Val(S, Result, E);
26 End;
28 procedure PrintIncorrectos();
29 var i : byte;
30 begin
31 for i := 0 to Cuenta do
32 Write(Puntos[i].Num, ' ');
33 WriteLn('are not the vertices of an acceptable figure');
34 end;
36 procedure PrintCorrecto(Figura : String);
37 var i : byte;
38 begin
39 for i := 0 to Cuenta do
40 Write(Puntos[i].Num, ' ');
41 WriteLn('are the vertices of a '+Figura);
42 end;
44 function GetFila(Numero : Integer) : Integer;
45 //retorna la fila de un numero o punto
46 var
47 Fila, Acum : Integer;
48 begin
49 Fila := 1;
50 Acum := 0;
51 repeat
52 Acum := Acum + Fila;
53 If Acum < Numero then
54 Fila := Fila + 1;
55 until Acum >= Numero;
56 Result := Fila; //Return
57 end;
59 function GetSumaDeFilas(Cuantas : Integer) : Integer;
60 //retorna la suma de todas las filas hasta Cuantas
61 var
62 i : integer;
63 begin
64 Result := 0;
65 For i := 1 to Cuantas do
66 Result := Result + i;
67 end;
69 function GetPosIzq(Numero, Fila : Integer) : Integer;
70 //retorna la posición izquierda respecto a la fila
71 begin
72 Result := Numero - (GetSumaDeFilas(Fila)-Fila);
73 end;
75 function GetPosDcha(Numero, Fila : Integer) : Integer;
76 //retorna la posición derecha respecto a la fila
77 begin
78 Result := GetSumaDeFilas(Fila) - Numero + 1;
79 end;
82 begin
83 PtsCorrectos := [3, 4, 6];
85 while not eof(input) do
86 begin
87 FillChar(Puntos, SizeOf(Puntos), 0); //Limpia el arreglo y lo llena todo con 0's
88 Cuenta := -1;
89 ReadLn(Entrada);
90 If Length(Entrada) = 0 then Break; //si no introducen ningun caracter entonces salir
91 If Entrada[Length(Entrada)] <> ' ' then Entrada := Entrada + ' '; //Agrega un espacio al final para poder "parsear" todos los numeros
92 While Pos(' ', Entrada) > 0 do
93 begin
94 Cuenta := Cuenta + 1;
95 Puntos[Cuenta].Num := StrToInt(Copy(Entrada, 1, Pos(' ', Entrada)-1));
96 Delete(Entrada, 1, Pos(' ', Entrada));
97 end;
98 //Aquí ya he leído todos los puntos y están en el arreglo Puntos. La variable Cuenta contiene el numero de elementos que hay
100 if not ((Cuenta+1) in PtsCorrectos) then //No son 3, 4 o 6 pts, entonces es incorrecto
101 begin
102 PrintIncorrectos();
103 Continue; //Salta al pròximo while
104 end;
106 for i := 0 to Cuenta do
107 begin
108 Puntos[i].Fila := GetFila(Puntos[i].Num);
109 Puntos[i].PosIzq := GetPosIzq(Puntos[i].Num, Puntos[i].Fila);
110 Puntos[i].PosDcha := GetPosDcha(Puntos[i].Num, Puntos[i].Fila);
111 end;
113 FillChar(PuntosOrdenados, SizeOf(PuntosOrdenados), 0);
114 //Organizarlos de mayor a menor
116 for i := 0 to Cuenta do
117 PuntosOrdenados[i] := Puntos[i]; //copia el arreglo
119 for i := 0 to Cuenta do
120 begin
121 for j := Cuenta downto i+1 do
122 begin
123 if PuntosOrdenados[j].Num < PuntosOrdenados[j-1].Num then
124 begin
125 TempPt := PuntosOrdenados[j];
126 PuntosOrdenados[j] := PuntosOrdenados[j-1];
127 PuntosOrdenados[j-1] := TempPt;
128 end;
129 end;
130 end;
131 //Aqui se encuentran todos los puntos organizados de mayor a menor en el arreglo PuntosOrdenados
133 case (Cuenta+1) of
135 /////////////////////////////////////////////
136 ////////////// Triangulo ////////////////////
137 /////////////////////////////////////////////
138 // _
139 3: //Triangulo : Hay 2 Tipos: \/ y /_\
140 begin
141 if PuntosOrdenados[0].Fila = PuntosOrdenados[1].Fila then //Tipo 1: Los dos primeros puntos estan en la misma fila
142 begin
143 Distancia1 := PuntosOrdenados[0].PosDcha - PuntosOrdenados[1].PosDcha;
144 if (PuntosOrdenados[2].PosDcha = PuntosOrdenados[0].PosDcha)
145 and (PuntosOrdenados[2].PosIzq = PuntosOrdenados[1].PosIzq)
146 and ((PuntosOrdenados[2].Fila - PuntosOrdenados[0].Fila) = Distancia1) then
147 begin
148 PrintCorrecto('triangle');
149 Continue;
151 else
152 begin
153 PrintIncorrectos();
154 Continue;
155 end;
157 else if PuntosOrdenados[1].Fila = PuntosOrdenados[2].Fila then //Tipo 2: El 2do y 3er punto estan en la misma fila
158 begin
159 Distancia1 := PuntosOrdenados[1].PosDcha - PuntosOrdenados[2].PosDcha;
160 if (PuntosOrdenados[1].PosIzq = PuntosOrdenados[0].PosIzq)
161 and (PuntosOrdenados[2].PosDcha = PuntosOrdenados[0].PosDcha)
162 and ((PuntosOrdenados[2].Fila - PuntosOrdenados[0].Fila)=Distancia1) then
163 begin
164 PrintCorrecto('triangle');
165 Continue;
167 else
168 begin
169 PrintIncorrectos();
170 Continue;
171 end;
173 else //No hay 2 puntos en la misma fila
174 begin
175 PrintIncorrectos();
176 Continue;
177 end;
178 end;
180 /////////////////////////////////////////////
181 ////////////// Paralelogramo ////////////////
182 /////////////////////////////////////////////
185 begin // _ _
186 if PuntosOrdenados[0].Fila = PuntosOrdenados[1].Fila then // tipo /_/ o \_\
187 begin
188 Distancia1 := PuntosOrdenados[0].PosDcha - PuntosOrdenados[1].PosDcha;
189 if ((PuntosOrdenados[2].PosIzq = PuntosOrdenados[0].PosIzq)
190 and (PuntosOrdenados[3].PosIzq = PuntosOrdenados[1].PosIzq)
191 and ((PuntosOrdenados[2].Fila-PuntosOrdenados[0].Fila)=Distancia1))
193 ((PuntosOrdenados[2].PosDcha = PuntosOrdenados[0].PosDcha)
194 and (PuntosOrdenados[3].PosDcha = PuntosOrdenados[1].PosDcha)
195 and ((PuntosOrdenados[2].Fila-PuntosOrdenados[0].Fila)=Distancia1)) then
196 begin
197 PrintCorrecto('parallelogram');
198 Continue;
200 else
201 begin
202 PrintIncorrectos();
203 Continue;
204 end;
205 end // /\
206 else if PuntosOrdenados[1].Fila = PuntosOrdenados[2].Fila then // tipo \/
207 begin
208 Distancia1 := PuntosOrdenados[1].Fila - PuntosOrdenados[0].Fila;
209 if (PuntosOrdenados[1].PosIzq = PuntosOrdenados[0].PosIzq)
210 and (PuntosOrdenados[2].PosDcha = PuntosOrdenados[0].PosDcha)
211 and ((PuntosOrdenados[3].Fila-PuntosOrdenados[1].Fila)=Distancia1)
212 and (PuntosOrdenados[3].PosDcha = PuntosOrdenados[1].PosDcha)
213 and (PuntosOrdenados[3].PosIzq = PuntosOrdenados[2].PosIzq) then
214 begin
215 PrintCorrecto('parallelogram');
216 Continue;
218 else
219 begin
220 PrintIncorrectos();
221 Continue;
222 end;
224 else
225 begin
226 PrintIncorrectos();
227 Continue;
228 end;
229 end;
232 /////////////////////////////////////////////
233 /////////////// Hexagono ////////////////////
234 /////////////////////////////////////////////
237 begin //Solo hay un tipo posible
238 Distancia1 := PuntosOrdenados[0].PosDcha - PuntosOrdenados[1].PosDcha;
239 if (PuntosOrdenados[0].Fila = PuntosOrdenados[1].Fila)
240 and (PuntosOrdenados[2].PosIzq = PuntosOrdenados[0].PosIzq)
241 and (PuntosOrdenados[3].PosDcha = PuntosOrdenados[1].PosDcha)
242 and (PuntosOrdenados[2].Fila - PuntosOrdenados[0].Fila = Distancia1)
243 and (PuntosOrdenados[4].PosDcha = PuntosOrdenados[2].PosDcha)
244 and (PuntosOrdenados[5].PosIzq = PuntosOrdenados[3].PosIzq)
245 and (PuntosOrdenados[4].Fila - PuntosOrdenados[2].Fila = Distancia1) then
246 begin
247 PrintCorrecto('hexagon');
248 Continue;
250 else
251 begin
252 PrintIncorrectos();
253 Continue;
254 end;
255 end;
256 end;//case
258 end;
259 end.